using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using FinanceStats.Entities;

namespace FinanceStats.Business.Components
{
    public partial class TotalCostGraphics : UserControl
    {
        private List<OutcomeDay> costData;
        private Dictionary<DateTime, Decimal?> euroCourseList;
        private int thousandNum = 10;
        private int rectangleWidht;
        private int originalWidth = 0;
        private Bitmap graph;

        public int ThousandNum
        {
            get { return thousandNum; }
            set { thousandNum = value; }
        }

        public List<OutcomeDay> CostData
        {
            get { return costData; }
            set 
            {
                if (costData != value)
                {
                    costData = value;
                    Redraw();
                    this.Refresh();
                }
            }
        }

        public Dictionary<DateTime, Decimal?> EuroCourseList
        {
            get { return euroCourseList; }
            set 
            {
                if (euroCourseList != value)
                {
                    euroCourseList = value;
                    Redraw();
                    this.Refresh();
                }
            }
        }


        public TotalCostGraphics()
        {
            InitializeComponent();
            this.graph = new Bitmap(this.Width, this.Height);
        }

        private void TotalCostGraphics_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawImage(this.graph, 0, 0);
        }

        private void DrawGrid(Graphics g)
        {
            Pen p = new Pen(Color.LightBlue, 1);
            if (rectangleWidht == 1)
            {
                rectangleWidht = 2;
            }
            for (int i = 0; i <= costData.Count; i++)
            {
                g.DrawLine(p, i * rectangleWidht, 0, i * rectangleWidht, this.Height);
            }
            int lineHeight = this.Height / this.thousandNum;
            for (int i = 0; i <= this.thousandNum; i++)
            {
                g.DrawLine(p, 0, this.Height - (i * lineHeight) - 5, this.Width, this.Height - (i * lineHeight)- 5);
            }
        }

        private decimal DrawEuroCourse(Graphics g)
        {
            Pen p = new Pen(Color.Orange, 1);
            List<Point> points = new List<Point>();
            decimal euroTotal = 0;
            for (int i = 0; i < costData.Count; i++)
            {
                OutcomeDay d = costData[i];
                Point point = new Point();
                point.X = i * rectangleWidht + rectangleWidht / 2;
                if (euroCourseList.ContainsKey(d.Date) && euroCourseList[d.Date] != null)
                {
                    int height = (int)((decimal)this.Height / (decimal)(this.thousandNum * 10) * (decimal)euroCourseList[d.Date]);
                    point.Y = this.Height - height + 5;
                    euroTotal += d.Total / (decimal)euroCourseList[d.Date];
                }
                else
                {
                    point.Y = this.Height - 5;
                }
                points.Add(point);
            }
            if (points.Count > 1)
            {
                points.Insert(0, new Point(rectangleWidht / 2, this.Height - 5));
                g.DrawLines(p, points.ToArray());
            }
            return euroTotal;
        }

        private void DrawStats(Graphics g, decimal total, decimal average, decimal euroTotal)
        {
            Rectangle r = new Rectangle(0, 0, 130, 60);
            g.FillRectangle(Brushes.LightSteelBlue, r); 
            Font f = new Font("Arial", 10, FontStyle.Regular);
            string tot = String.Format("Total: {0}", total.ToString("#.##"));
            g.DrawString(tot, f, Brushes.Blue, 5, 5);
            tot = String.Format("Average: {0}", average.ToString("#.##"));
            g.DrawString(tot, f, Brushes.Red, 5, 20);
            tot = String.Format("Total (euro): {0}", euroTotal.ToString("#.##"));
            g.DrawString(tot, f, Brushes.DarkOliveGreen, 5, 35);
        }

        private void Redraw()
        {
            this.graph = new Bitmap(this.Width, this.Height);
            if (this.costData != null && this.euroCourseList != null)
            {
                Graphics g = Graphics.FromImage(this.graph);
                this.rectangleWidht = this.Width / costData.Count;
                if (rectangleWidht == 1)
                {
                    this.originalWidth = this.Width;
                    rectangleWidht = 2;
                    this.Width = rectangleWidht * costData.Count;
                }
                else if (this.originalWidth != 0)
                {
                    this.Width = this.originalWidth;
                }
                DrawGrid(g);
                List<Rectangle> rectangles = new List<Rectangle>();
                decimal total = 0;
                int count = 0;
                for (int i = 0; i < costData.Count; i++)
                {
                    OutcomeDay d = costData[i];
                    Rectangle r = new Rectangle();
                    r.Width = rectangleWidht;
                    r.Height = (int)((decimal)this.Height / (decimal)(this.thousandNum * 1000) * d.Total);
                    r.X = i * rectangleWidht;
                    r.Y = this.Height - r.Height - 5;
                    rectangles.Add(r);
                    if (d.Total > 0)
                    {
                        total += d.Total;
                        count++;
                    }
                }
                Pen p = new Pen(Color.Red, 1);
                int average = 0;
                if (count > 0)
                {
                    average = (int)((decimal)this.Height / (decimal)(this.thousandNum * 1000) * (total / count));
                    g.DrawLine(p, 0, this.Height - average - 5, this.Width, this.Height - average - 5);
                }
                for (int i = 0; i < rectangles.Count; i++)
                {
                    Rectangle r = rectangles[i];
                    if (average != 0 && r.Height > average)
                    {
                        p.Color = Color.Red;
                    }
                    else
                    {
                        p.Color = Color.Blue;
                    }
                    g.FillRectangle(p.Brush, r);
                }
                decimal euroTotal = DrawEuroCourse(g);
                DrawStats(g, total, total / costData.Count, euroTotal);
            }
        }
    }
}
